#include "os_sal.h"


/* os event 事件标志位 */


/* export func */


#if (CONFIG_OS_ENABLE == 1)

#if defined(CONFIG_OS_TYPE_FREERTOS)

#include "FreeRTOS.h"
#include "event_groups.h"


/**
 * @brief OS创建事件标记组
 * 
 * @return os_event_handle_t 事件句柄
 */
os_event_handle_t os_event_create(void)
{
	os_event_handle_t event; 

	event = xEventGroupCreate();
	return event;
}

/**
 * @brief OS删除事件标记组
 * 
 * @param event 事件句柄
 * @return os_status_t 
 */
os_status_t os_event_delete(os_event_handle_t event)
{
	if (event == NULL) return OS_STA_ERROR;
	vEventGroupDelete(event);
	return OS_STA_SUCCESS;
}

/**
 * @brief OS事件标记组设置事件
 * 
 * @param event 事件句柄
 * @param value 置位后的事件值
 * @param bits 位
 * @return os_status_t 
 */
os_status_t os_event_set_bits(os_event_handle_t event, uint32_t *value, uint32_t bits)
{
	os_status_t os_sta;
	uint32_t ret;
	BaseType_t pxHigherPriorityTaskWoken = pdFALSE;
	uint8_t isrcount = 0;

	if (event == NULL) return OS_STA_ERROR;
	isrcount = ulPortGetIPSR();
	if (isrcount > 0)
	{
		ret = xEventGroupSetBitsFromISR(event, bits, &pxHigherPriorityTaskWoken);
		if (ret == pdPASS) os_sta = OS_STA_SUCCESS;
		else os_sta = OS_STA_ERROR;
		if (value) *value = bits;
		if((pdTRUE == pxHigherPriorityTaskWoken) && (1 == isrcount))
		{			
			portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
		}	
	}
	else
	{
		ret = xEventGroupSetBits(event, bits);
		os_sta = OS_STA_SUCCESS;
		if (value) *value = ret;
		
	}

	return os_sta;
}

/**
 * @brief OS事件标记组等待事件
 * 
 * @param event 事件句柄
 * @param value 结果
 * @param bits 位
 * @param flag_clear_exit 退出时是否清除事件
 * @param flag_wait_all_bits 等待全部事件？
 * @param waittime 等待时间
 * @return os_status_t 
 */
os_status_t os_event_wait_bits(os_event_handle_t event, uint32_t *value, uint32_t bits, os_bool_t flag_clear_exit, os_bool_t flag_wait_all_bits, uint32_t waittime)
{
	uint32_t ret;

	if (event == NULL) return OS_STA_ERROR;
	ret = xEventGroupWaitBits(event, bits, flag_clear_exit, flag_wait_all_bits, waittime);
	if (value) *value = ret;
	return OS_STA_ERROR;
}

/**
 * @brief OS事件标记组直接获取事件
 * 
 * @param event 事件句柄
 * @param value 结果
 * @return os_status_t 
 */
os_status_t os_event_get_bits(os_event_handle_t event, uint32_t *value)
{
	uint32_t ret;
	uint8_t isrcount = 0;

	if (event == NULL) return OS_STA_ERROR;
	isrcount = ulPortGetIPSR();
	if (isrcount > 0)
	{
		ret = xEventGroupGetBitsFromISR(event);
	}
	else
	{
		ret = xEventGroupGetBits(event);
	}

	if (value) *value = ret;
	return OS_STA_SUCCESS;
}

/**
 * @brief OS事件标记组清除事件
 * 
 * @param event 事件句柄
 * @param value 指定事件清除之前的值
 * @param bits 需要清除的事件
 * @return os_status_t 
 */
os_status_t os_event_clear_bits(os_event_handle_t event, uint32_t *value, uint32_t bits)
{
	os_status_t os_sta;
	uint32_t ret;
	uint8_t isrcount = 0;

	if (event == NULL) return OS_STA_ERROR;
	isrcount = ulPortGetIPSR();
	if (isrcount > 0)
	{
		ret = xEventGroupClearBitsFromISR(event, bits);
		if (ret == pdPASS) os_sta = OS_STA_SUCCESS;
		else os_sta = OS_STA_ERROR;
	}
	else
	{
		ret = xEventGroupClearBits(event, bits);
		os_sta = OS_STA_SUCCESS;
		
	}
	
	if (value) *value = ret;
	return os_sta;
}



#else
    #error "CONFIG_OS_TYPE not support!"
#endif // CONFIG_OS_TYPE

#endif // CONFIG_OS_ENABLE


